
// vue3中 createApp方法每执行一次 都会生成一个独立的vue应用实例
// 而每一个独立的应用实例 各自拥有自己的`作用域` 并不会共享全局指令
// 如果想共享 这里必须使用由main.js中 有createApp方法产出的app实例
// 解决思路 把全局指令的定义写成插件的形式
// 依靠注册插件时的use方法就可以拿到main.js中的唯一实例

//  插件形式 注册全局指令
// 1. createApp 生成一个app实例对象
// 2. app.directive('指令名称', { 指令的配置项 })

// 引入监听是否进入视口
import { useIntersectionObserver } from '@vueuse/core'

// 引入默认图片  在图片发生加载错误时使用
import defaultImg from '@/assets/images/200.png'

export default {
  // 拿到main.js中由createApp方法产出的app实例对象
  install (app) {
    app.directive('imgLazy', {
      // 指令挂载到节点上时立刻执行, 并且只执行一次 相当于vue2的 inserted函数
      mounted (el, binding) {
        // el: 绑定指令的原生dom对象
        // binding.value   v-imgLazy="这里表达式的值"
        // console.log('指令参数', el, binding.value)
        // 图片懒加载逻辑实现：当前的el对象进入到视口之后 我们才加载图片对应的url
        // 使用 useIntersectionObserver监听api,对图片dom进行监听 正式进入视口才加载
        const { stop } = useIntersectionObserver(
          el, // 监听的目标元素
          ([{ isIntersecting }], observerElement) => {
            // 图片dom进入可视区域
            if (isIntersecting) {
              // 当图片url无效加载失败的时候使用默认图片替代
              el.addEventListener('error', () => {
                el.src = defaultImg
              })
              // 在这里把url交给src属性
              el.src = binding.value // <img v-imgLazy = "url"/>
              // 图片成功加载出来后，停止再次获取
              stop()
            }
          },
          // dom节点刚进入视口区域就立刻执行回调 0 - 1
          { threshold: 0 }
        )
      }
    })
  }
}
